Request/Callback services
There
are cases where the caller of a service wants the benefits of
non-blocking asynchronous service invocation, but also needs an actual
data response from the service. In this case, a callback pattern can
best fit your needs. In this situation, the caller acts as both a
service consumer and a service provider. That is, the caller must be
able to both send a message, and host an endpoint that the service can
send a subsequent response to. You can consider this an asynchronous
request/response pattern.
This
can be a complicated pattern for service callers to accommodate. The
caller has to design some intelligent strategies to correlate
out-of-band responses with the original request made. During
request/response invocations, the caller is blocked and doesn't proceed
until the response has arrived. A sequence of processing is preserved.
In a callback scenario, the client receives service responses well
after the initial request. They have to make sure that:
Additionally, the client application should take into account the fact that a response may never actually arrive.
How
does the service know where to send its response message back to?
Typically the inbound request contains a pointer to the callback URI.
The SOAP header is a good place to cram this sort of metadata instead
of polluting the actual data message with context information.
WCF has some fairly rich support for callbacks through bindings such as the NetTcpBinding and NetNamedPipeBinding.
While HTTP is inherently stateless and doesn't naturally support
bidirectional communication, WCF provides a special HTTP binding named WSDualHttpBinding,
which creates a matching pair of directional channels under the covers.
A WCF developer can add callback contracts to a service contract and
allow WCF clients to seamlessly call services and have an event raised
when the service response is eventually received.
Sounds great, right? Unfortunately, the BizTalk WCF adapters do not openly support the WSDualHttpBinding
or callback contracts in general. Instead, as we’ll investigate in
depth during Chapter 6, we need to get creative through the use of
dynamic ports or polling strategies to implement a general purpose,
cross platform callback patterns. That said, I will show you in Chapter
6 how you CAN effectively use the WSDualHttpBinding within a BizTalk
receive location.
Publish/Subscribe services
This
final MEP is actually an extension of the one-way MEP. Instead of a
sender and receiver of a service, consider the parties to be a
publisher and subscriber. In a publish/subscribe MEP, data objects are
sent to an endpoint where a dynamic set of interested entities yank a
copy of the data for their own purpose. There is a one-to-many
relationship between the publisher and subscribers. The data is
published to the service in an asynchronous fashion with no expectation
of a direct response.
BizTalk
excels at the publish/subscribe service pattern. BizTalk can optionally
subscribe on three distinct pieces of information:
Message context: Each message that arrives into BizTalk Server has a property bag called context
attached to it. Regardless of whether the data is in a structured data
format (such as XML) or a binary blob (such as a PDF file), any object
reaching the BizTalk MessageBox has context attached. Message
subscribers can decide to register interest in topics associated with
the message metadata found in context. For instance, a subscriber might
choose to listen for all messages that arrived at a specific file
location. Hence, their send port subscription would equal BTS.ReceivedFileName.
Message Type: A message with a structured data format can be typed by the BizTalk endpoint prior to publication to the bus. The type
value is typically equal to the namespace of the XML message plus the
name of the root node. BizTalk subscribers can choose to pull any
message that matches the data type they are interested in.
Message Content. Developers can single out fields in a message schema for promotion
which means that they are available for routing decisions within the
BizTalk bus. When a message arrives into BizTalk, and a matching schema
is found, the data elements designated for promotion have their values
yanked out of the payload and put into context. Downstream subscribers
can now specify data-level subscription topics. Hence, instead of
pulling all new employees from the bus (based on a message type
subscription), we could extract only those where EmployeeCountry == Germany using a content based subscription.
Pitfall
While
BizTalk Server offers a variety of subscription topic mechanisms
(context, type, or content), you are limited by the subscription
operators available. For instance, you cannot create a subscription
where "Organization CONTAINS Hospital". That is, you do not have
options for wildcard searches or dynamic subscriptions in a send port.
To achieve such a capability, you'd have to rely on orchestrations or
custom pipeline components.
This
manner of service invocation shifts the idea of a service from being
just a functional component in a fancy SOAP wrapper to being an on-ramp
to a distributed computing bus, where the publisher relinquishes
knowledge and control of the data's processing path.